# Variable globale definissant la frequence de ping
set var_pingFrequence 500

# Delai apres lequel on supprime un voisin de la liste si on a pas recu de reponse (en ms)
set const_delaiSuppressionVoisin 5000

#Delai entre chaque affichage de la liste des voisins (en ms)
set const_delaiAffichageListeVoisins 1000

################################################################################
#
# Procedure generale de traitement des messages de type "ping"
#
# => param_type : type du message recu
# => param_message : contenu du message (tout sauf le type)
#
################################################################################
proc proc_traiterMessageTypePing { param_type param_message } {
	switch $param_type {
		"20" {
			array set var_ping [proc_parsePing $param_message]
			proc_envoi [proc_construireReponsePing [proc_getMonId] $var_ping(emmeteurId) $var_ping(dateEnvoi)]
		}
		"21" {			
			proc_voisinsTraiterReponsePing [proc_parseReponsePing $param_message]
		}
	}
}



################################################################################
#
# Initialise l'envoie regulier des pings
#
################################################################################
proc proc_initPing { } {
		global var_pingFrequence
	
		# programmation de la prochaine emission
		after $var_pingFrequence proc_envoiPing
}


################################################################################
#
# Procedure de signalisation a ses voisins
#   * Comme on attend une reponse, on peut calculer la distance de nos voisins
#     (on met notre date locale a laquelle on a envoye le ping
#     a la reception de la reponse, on calule le temps)
#   * A chaque envoi, on verifie aussi si les voisins que l'on connaissait
#     sont toujours la (on a eu des nouvelles recemment)
#
################################################################################
proc proc_envoiPing { } {
		global var_pingFrequence
		global const_delaiSuppressionVoisin

		# Envoi du ping
		proc_envoi [proc_construirePing [proc_getMonId] [clock clicks -milliseconds]]

		# Recupere la liste des ids de nos voisins
		set var_listeVoisinsId [proc_getListeVoisinsId]
		
		# Regarde si les voisins sont encore la
		foreach var_idNoeud $var_listeVoisinsId {
			# Voisin introuvable
			if { [expr {[clock clicks -milliseconds] - [proc_getVoisinDernierContact $var_idNoeud]}] > $const_delaiSuppressionVoisin } {
				proc_supprimerVoisin $var_idNoeud
			}
		}	
		# programmation de la prochaine emission
		after $var_pingFrequence proc_envoiPing
}


################################################################################
#
# Procedure de traitement des ping
#   * Avec la date d'envoi dans le message, on peut calculer la distance de ce 
#     voisin (date envoi - date actuelle)
#   * On stocke la date a laquelle il nous a anvoye de ses nouvelles pour la 
#     derniere fois
#
################################################################################
proc proc_voisinsTraiterReponsePing { param_messageListe } {

	array set var_reponsePing $param_messageListe
	
	# Verifie si c'est une reponse a un de nos ping
	if { $var_reponsePing(destinataireId) == [proc_getMonId] } {
		# on memorise les informations (id du noeud, date de dernier contact : maintenant, distance)
		proc_ajouterVoisin $var_reponsePing(emmeteurId)
		proc_voisinSetDernierContact $var_reponsePing(emmeteurId) [clock clicks -milliseconds]
		proc_voisinSetDistance $var_reponsePing(emmeteurId) [expr {([clock clicks -milliseconds] - $var_reponsePing(dateEnvoi))/2 }]

	}
}
